import {PARAMS} from '@/api/http';
import {TreeNode} from 'element-ui/types/tree';
import moment from 'moment';
import {VueConstructor} from 'vue';
import {Route} from 'vue-router';

moment.locale('zh-cn');

/**
 * 解析参数
 * @param params 参数表
 * @param route vue route对象
 */
function parseParams(params: PARAMS, route: Route): void {
  const t = route.query as { [key: string]: any };

  Object.keys(t).forEach((k) => {
    if (k === 'pageId' || k === 'pageSize') {
      // tslint:disable-next-line:radix
      const v = parseInt(t[k] as string);

      if (!isNaN(v)) {
        params[k] = v;
      }
    } else {
      params[k] = t[k];
    }
  });
}

/**
 * 格式化url参数
 * @param params 参数表
 * @return url参数
 */
function formatParamsUrl(params: PARAMS): string {
  let str = '?';
  Object.keys(params).forEach((k) => {
    if (params[k]) {
      str += (k + '=' + params[k] + '&');
    }
  });

  return str.length === 1 ? '' : str;
}

/**
 * 展开树
 * @param table element-ui table元素节点表
 */
function expandTree(table: TreeNode<any, any>): void {
  if (!table) {
    return;
  }

  const store = table.store;
  const treeData = store.states.treeData;
  for (const id in treeData) {
    if (!treeData.hasOwnProperty(id)) {
      continue;
    }
    const data = treeData[id];
    if (Array.isArray(data.children) && data.children.length > 0 && 'expanded' in data) {
      data.expanded = true;
    }
  }
  store.updateTableScrollY();
}

/**
 * 关闭树
 * @param table element-ui table元素节点表
 */
function contractTree(table: TreeNode<any, any>): void {
  if (!table) {
    return;
  }

  const store = table.store;
  const treeData = store.states.treeData;
  for (const id in treeData) {
    if (!treeData.hasOwnProperty(id)) {
      continue;
    }
    const data = treeData[id];
    if (Array.isArray(data.children) && data.children.length > 0 && 'expanded' in data) {
      data.expanded = false;
    }
  }
  store.updateTableScrollY();
}

/**
 * 判断是否为完整url
 * @param url url
 * @return 是否为完整url
 */
function isCompleteUrl(url: string): boolean {
  return url == null || url.startsWith('//') || url.startsWith('http://') || url.startsWith('https://');
}

/**
 * 获取上传资源链接
 * @param url url
 * @return 拼接后url
 */
function getImageUrl(url: string): string {
  if (isCompleteUrl(url)) {
    return url;
  }

  return process.env.VUE_APP_UPLOAD_URL + url;
}

/**
 * 获取上传资源的缩略图链接
 * @param url url
 * @param w 宽
 * @param h 高
 * @return 拼接后url
 */
function getPreviewImageUrl(url: string, w: string | number, h: string | number): string {
  if (isCompleteUrl(url)) {
    return url;
  }

  return process.env.VUE_APP_UPLOAD_URL + url + '_' + w + 'x' + h + '.jpg';
}

/**
 * 时间日期格式化处理
 * @param val 值
 * @param pattern 目标格式
 * @param defaultVal 默认值
 * @param defaultPattern 默认格式
 * @return 格式化后的文本值
 */
function datetimeFormat0(val: string | number,
                         pattern?: string,
                         defaultVal?: string,
                         defaultPattern?: string): string | undefined {
  if (val) {
    return moment(val).format(pattern ? pattern : defaultPattern);
  } else {
    return defaultVal;
  }
}

/**
 * 时间格式化
 * @param val 值
 * @param pattern 目标格式
 * @param defaultVal 默认值
 * @return 格式化后的文本值
 */
function timeFormat(val: string | number,
                    pattern?: string,
                    defaultVal?: string): string | undefined {
  return datetimeFormat0(val, pattern, defaultVal, process.env.VUE_APP_DEFAULT_TIME_FORMAT);
}

/**
 * 日期格式化
 * @param val 值
 * @param pattern 目标格式
 * @param defaultVal 默认值
 * @return 格式化后的文本值
 */
function dateFormat(val: string | number,
                    pattern?: string,
                    defaultVal?: string): string | undefined {
  return datetimeFormat0(val, pattern, defaultVal, process.env.VUE_APP_DEFAULT_DATE_FORMAT);
}

/**
 * 日期时间格式化
 * @param val 值
 * @param pattern 目标格式
 * @param defaultVal 默认值
 * @return 格式化后的文本值
 */
function datetimeFormat(val: string | number,
                        pattern?: string,
                        defaultVal?: string): string | undefined {
  return datetimeFormat0(val, pattern, defaultVal, process.env.VUE_APP_DEFAULT_DATETIME_FORMAT);
}

/**
 * 打开新窗口预览元素
 * @param uri url
 */
function preview(uri: string): void {
  window.open(getImageUrl(uri));
}

/**
 * 判断是否为系统职位
 * @param id 职位ID
 * @return 是否为系统职位
 */
function isSystemDuty(id: string | number): boolean {
  return id <= 3;
}

/**
 * 判断是否为部门管理职位
 * @param id 职位ID
 * @return 是否为部门管理职位
 */
function isManagerDuty(id: string | number): boolean {
  return id === 1 || id === 2;
}

/**
 * 判断是否为默认头像
 * @param url 头像url
 * @return 是否为默认头像
 */
function isDefaultAvatar(url?: string): boolean {
  return process.env.VUE_APP_DEFAULT_AVATAR_URL === url;
}

/**
 * 货币格式化对象
 */
const CurrencyFormatter = new Intl.NumberFormat('zh-cn', {style: 'currency', currency: 'CNY'});

/**
 * 格式化货币
 * @param val 数值
 * return 格式化后的货币字符串
 */
function currencyFormat(val: number): string {
  return CurrencyFormatter.format(val);
}

export default {
  install(vue: VueConstructor) {
    Object.defineProperty(vue.prototype, '$moment', {value: moment});
    Object.defineProperty(vue.prototype, '$expandTree', {value: expandTree});
    Object.defineProperty(vue.prototype, '$contractTree', {value: contractTree});
    Object.defineProperty(vue.prototype, '$parseParams', {value: parseParams});
    Object.defineProperty(vue.prototype, '$getImageUrl', {value: getImageUrl});
    Object.defineProperty(vue.prototype, '$getPreviewImageUrl', {value: getPreviewImageUrl});
    Object.defineProperty(vue.prototype, '$preview', {value: preview});
    Object.defineProperty(vue.prototype, '$formatParamsUrl', {value: formatParamsUrl});
    Object.defineProperty(vue.prototype, '$isSystemDuty', {value: isSystemDuty});
    Object.defineProperty(vue.prototype, '$isManagerDuty', {value: isManagerDuty});
    Object.defineProperty(vue.prototype, '$isDefaultAvatar', {value: isDefaultAvatar});

    vue.filter('currencyFormat', currencyFormat);
    vue.filter('timeFormat', timeFormat);
    vue.filter('dateFormat', dateFormat);
    vue.filter('datetimeFormat', datetimeFormat);
  }
};
